package cn.xtits.xtf.common.db;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import cn.xtits.xtf.common.exception.XTDbException;

import cn.xtits.xtf.common.spring.SpringContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Properties;

/**
 *
 */
public class DynamicReloadDataSource implements InitializingBean {
    public static final Logger logger = LoggerFactory.getLogger(DynamicReloadDataSource.class);

    private static final String DATA_SOURCE_BEAN_NAME = "xtDbRouter";
    private static final String DATABASE_CONFIG_FILE = "dynamic-datasource.properties";
    private static final String AREA_DATASOURCE_KEYS = "area.datasource.keys";
    private static final String USER_DATASOURCE_KEYS = "user.datasource.keys";
    private static final String JDBC_DRIVER_CLASS_KEY ="%s.jdbc.driver.class";
    private static final String JDBC_URL_KEY = "%s.jdbc.url";
    private static final String JDBC_USERNAME_KEY = "%s.jdbc.username";
    private static final String JDBC_PASSWORD_KEY = "%s.jdbc.password";

    private Object mutex = new Object();

    @Override
    public void afterPropertiesSet() throws Exception {
        loadConfig();
    }

    public void reload() {
        loadConfig();
    }

    private void loadConfig() {
        logger.info("begin load dynamic-datasource.properties ");
        synchronized (mutex) {
            Properties properties = new Properties();
            try {
                properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(DATABASE_CONFIG_FILE));
                String areaKeys =  properties.getProperty(AREA_DATASOURCE_KEYS);
                if (StringUtils.isNotEmpty(areaKeys)) reloadDbAreaConfig(areaKeys,properties);

                String userKeys =  properties.getProperty(USER_DATASOURCE_KEYS);
                if (StringUtils.isNotEmpty(userKeys)) reloadDbUserConfig(userKeys,properties);

            }catch (Exception e) {
                logger.error("loadConfig dynamic-datasource.properties error!,e : {}",e);
                throw new XTDbException("loadConfig dynamic-datasource.properties error!");
            }
        }
        logger.info("load dynamic-datasource.properties  success!");
    }

    private static void reloadDbAreaConfig(String areaKeys,Properties properties) {
        reloadDbConfig(areaKeys,properties,DbRouter.DB_KEY_AREA);
    }

    private static void reloadDbUserConfig(String areaKeys,Properties properties) {
        reloadDbConfig(areaKeys,properties,DbRouter.DB_KEY_USER);
    }

    private static void reloadDbConfig(String areaKeys,Properties properties,String type) {
        if(StringUtils.isNotEmpty(areaKeys)) {
            String[] keyArray = areaKeys.split(",");
            DbRouter dbRouter = SpringContext.getBean(DATA_SOURCE_BEAN_NAME);
            for(String key : keyArray) {
                try {
                    DataSource dataSource = createDataSource(properties, key);
                    if (type.equals(DbRouter.DB_KEY_AREA))  dbRouter.putNewAreaDataSourceToArea(key,dataSource);

                    if (type.equals(DbRouter.DB_KEY_USER))  dbRouter.putNewUserDataSourceToArea(key,dataSource);
                } catch (Exception e) {
                    logger.error("createDataSource error! , e : {}",e);
                    throw new XTDbException("createDataSource error!");
                }
            }
        }
    }

    /**
     * 创建数据源
     *
     * @param properties
     * @param key
     * @return
     * @throws Exception
     */
    private static DataSource createDataSource(Properties properties, String key) throws Exception {
        HashMap<String, String> druidMap = new HashMap<String, String>();
        druidMap.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, properties.getProperty(String.format(JDBC_DRIVER_CLASS_KEY, key)));
        druidMap.put(DruidDataSourceFactory.PROP_URL, properties.getProperty(String.format(JDBC_URL_KEY, key)));
        druidMap.put(DruidDataSourceFactory.PROP_USERNAME, properties.getProperty(String.format(JDBC_USERNAME_KEY, key)));
        druidMap.put(DruidDataSourceFactory.PROP_PASSWORD, properties.getProperty(String.format(JDBC_PASSWORD_KEY, key)));
        druidMap.put(DruidDataSourceFactory.PROP_INITIALSIZE, "1");
        druidMap.put(DruidDataSourceFactory.PROP_MAXACTIVE, "100");
        druidMap.put(DruidDataSourceFactory.PROP_MINIDLE, "5");
        druidMap.put(DruidDataSourceFactory.PROP_MAXIDLE, "10");
        druidMap.put(DruidDataSourceFactory.PROP_TESTWHILEIDLE, "true");
        druidMap.put(DruidDataSourceFactory.PROP_MAXWAIT, "60000");


        DataSource dataSource = DruidDataSourceFactory.createDataSource(druidMap);
        return dataSource;
    }


}
